//
//  TFFormTableViewController.m
//  WebPDA
//
//  Created by Justin Yip on 8/14/10.
//  Copyright 2010 TenNights.com. All rights reserved.
//

/* Tasks:
 */

#import "FTFormTableViewController.h"
#import "FTBaseCell.h"

//@interface FTFormTableViewControllerImpl : FTFormTableViewController
//{
//	NSMutableDictionary *valueCollector2;
//}
//
//
//
//@end
//
//@implementation FTFormTableViewControllerImpl
//
///*
// load Root table in bundle
// */
//-(void)loadBundle:(NSString *)bundleName {
//	[self loadFile:@"Root.plist" inBundle:bundleName];
//}
//
//@end



@implementation FTFormTableViewController
@synthesize formBundle;
@synthesize preferenceSpecifiers;
@synthesize sectionIndexes;
@synthesize valueHolder;
@synthesize navigationController;

#pragma mark -
#pragma mark Initialization

- (id)initWithStyle:(UITableViewStyle)style {
    // Override initWithStyle: if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
    if ((self = [super initWithStyle:style])) {
		//此控制器一般作为子组件，所以需要忽略状态栏
		self.wantsFullScreenLayout = YES;
    }
    return self;
}

//+ (id) allocWithZone:(NSZone *)zone
//{
//	return NSAllocateObject([FTFormTableViewControllerImpl class], 0, zone);
//}

#pragma mark -
#pragma mark Bundle Loading

-(void)loadBundle:(NSString *)bundleName {
	[self loadFile:@"Root" inBundleName:bundleName];
}

-(void)loadFile:(NSString*)fileName inBundleName:(NSString*)bundleName{
	//load bundle
	NSString *bundlePath = [[NSBundle mainBundle] pathForResource:bundleName ofType:@"bundle"];
	NSBundle *tmpBundle = [[NSBundle alloc] initWithPath:bundlePath];
	[self loadFile:fileName inBundle:tmpBundle];//call
	[tmpBundle release];
}

-(void)loadFile:(NSString*)fileName inBundle:(NSBundle*)bundle{
	self.formBundle = bundle;
	
	//load preferenceSpecifiers
	NSString *rootPath = [bundle pathForResource:fileName ofType:@"plist"];
	if (nil == rootPath) {
		NSLog(@"file '%@' not found in bundle: %@", fileName, [bundle bundlePath]);
		abort();
	}
	NSDictionary *rootDict = [[NSDictionary alloc] initWithContentsOfFile:rootPath];
	self.preferenceSpecifiers = [rootDict objectForKey:@"PreferenceSpecifiers"];//must retain here
	[rootDict release];
	
	//calculate section indexes
	NSMutableArray *tmpSectionIndexes = [[NSMutableArray alloc] init];
	for (NSInteger i=0; i< [preferenceSpecifiers count]; i++) {
		NSDictionary *preferenceSpecifier = [preferenceSpecifiers objectAtIndex:i];
		if ([[preferenceSpecifier objectForKey:@"Type"] isEqualToString:@"PSGroupSpecifier"]) {
			[tmpSectionIndexes addObject:[NSNumber numberWithInteger:i]];
		}
	}
	
	// detect no section in bundle, we need to simulate one
	if (![tmpSectionIndexes containsObject:[NSNumber numberWithInteger:0]] && [preferenceSpecifiers count] > 0) {
		//insert a fake section index
		[tmpSectionIndexes insertObject:[NSNumber numberWithInteger:0] atIndex:0];
		//insert a fake section preference specifier(nil)
		NSMutableArray *tmpPreferenceSpecifierArray = [[NSMutableArray alloc] initWithArray:preferenceSpecifiers];
		[tmpPreferenceSpecifierArray insertObject:[NSNumber numberWithInt:0] atIndex:0];
		self.preferenceSpecifiers = tmpPreferenceSpecifierArray;
		[tmpPreferenceSpecifierArray release];
	}
	
	self.sectionIndexes = tmpSectionIndexes;
	[tmpSectionIndexes release];
}

#pragma mark -
#pragma mark object binding

-(id)entity {
	return valueHolder.entity;
}

-(void)setEntity:(id)aEntity {
	NSLog(@"FormTable change entity, reload tableView");
	valueHolder.entity = aEntity;
	[self.tableView reloadData];
}

#pragma mark -
#pragma mark Editing

-(void)setEditing:(BOOL)editing animated:(BOOL)animated {
	if (nil == self.view.superview) {
		NSLog(@"Warning: the setEditing:animated: action may take no effect!\n\
			  FTFormTableViewController.view.superview = nil,\n\
			  it seems FTFormTableViewController.view refers to an empty tableView.\n\
			  you can try to connect FTFormTableViewController.view to the tableView in IB or by code.");
	}
	[super setEditing:editing animated:animated];
}

#pragma mark -
#pragma mark View lifecycle


- (void)viewDidLoad {
    [super viewDidLoad];
    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
	
	valueHolder = [[FTValueHolder alloc] init];
}



// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return YES;
}



#pragma mark -
#pragma mark Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
    return [sectionIndexes count];
}

- (NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
	//check bundle
	if (nil == formBundle) {
		NSLog(@"form bundle not exist.");
		abort();
	}
	
	//index of the required section
	NSInteger sectionIndex = [[sectionIndexes objectAtIndex:section] intValue];
	if ([[preferenceSpecifiers objectAtIndex:sectionIndex] isKindOfClass:[NSDictionary class]]) {
		
		NSString *title = [[preferenceSpecifiers objectAtIndex:sectionIndex] objectForKey:@"Title"];
		return NSLocalizedStringFromTableInBundle(title, @"Root", formBundle, @"");
	}else {
		
		//handle the fake ps
		return nil;
	}

}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // Return the number of rows in the section.
	
	//index of given section
	NSInteger sectionIndex = [[sectionIndexes objectAtIndex:section] intValue];

	//index of next section
	NSInteger nextSectionIndex = 0;
	if (section < [sectionIndexes count] - 1) {
		nextSectionIndex = [[sectionIndexes objectAtIndex:section + 1] intValue];
	}else {
		nextSectionIndex = [preferenceSpecifiers count];
	}

	NSInteger numberOfRows = nextSectionIndex - sectionIndex - 1;
	return numberOfRows;
}


// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
	
	//get the preference specifier of required cell
	NSInteger sectionIndex = [[sectionIndexes objectAtIndex:indexPath.section] intValue];
	NSInteger cellIndex = sectionIndex + indexPath.row + 1;
	NSDictionary *preferenceSpecifier = [preferenceSpecifiers objectAtIndex:cellIndex];
	
	//NOTE:we need a heavy cell!!??
	NSString *cellType = [preferenceSpecifier valueForKey:@"Type"];
	//extra the cell class name (PSTextFieldSpecifier -> FTTextFieldCell)
    NSString *cellClassName = [NSString stringWithFormat:@"FT%@Cell",
							   [cellType substringWithRange:NSMakeRange(2, [cellType length] - 11)] ];
	Class cellClass = NSClassFromString(cellClassName);
	if (nil != cellClass) {
		//we use cellClassName for reuse identifier
		FTBaseCell *cell = (FTBaseCell*)[tableView dequeueReusableCellWithIdentifier:cellClassName];
		if (nil == cell) {
			cell = [[[cellClass alloc] initWithBundle:formBundle valueHolder:valueHolder reuseIdentifier:cellClassName] autorelease];
		}
		// configure the cell with kvc & ps
		[cell configureWithObject:valueHolder preferenceSpecifier:preferenceSpecifier];
		return cell;
	}
	
	
	
	// unknown cell
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = (UITableViewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
    
    // Configure the cell...
	cell.textLabel.text = [NSString stringWithFormat:@"%d,%d,%@",indexPath.section, indexPath.row, cellType];
    
    return cell;
}

#pragma mark Editing

// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return NO if you do not want the specified item to be editable.
    return YES;
}

// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the row from the data source
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
    }   
    else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }   
}


/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
}
*/


/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return NO if you do not want the item to be re-orderable.
    return YES;
}
*/


#pragma mark -
#pragma mark Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
	//id v = self.navigationController;
	UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
	if ([cell respondsToSelector:@selector(didSelected:)]) {
		[cell performSelector:@selector(didSelected:) withObject:self.navigationController];
		[tableView deselectRowAtIndexPath:indexPath animated:YES];
	}
}


#pragma mark -
#pragma mark Memory management

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
    
    // Relinquish ownership any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    // Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
    // For example: self.myOutlet = nil;
}


- (void)dealloc {
	[valueHolder release];
	[formBundle release];
	[preferenceSpecifiers release];
	[sectionIndexes release];
	[navigationController release];
    [super dealloc];
}


@end

